#include "link_list.h"



// 单链表的创建
int init_link_list(link_list ** list)
{
    // 1 创建 头结点
    *list = (link_list *)malloc(sizeof(link_list));

    if (NULL == *list)
    {
        ERRLOG("头结点创建失败");
        return EOF;
    }

    // 2 初始化头节点
    (*list)->next = NULL;

    return 0;
}


// 单链表的插入
int insert_link_list(link_list* list, Elenemt_data data, int pos)
{
    if (NULL == list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }

    if (0 == pos)
    {
        printf("pos 不能为 0\n");
        return EOF;
    }

    // 创建 结点 的空间
    Node * new_node = (Node *)malloc(sizeof(Node));

    if (NULL == new_node)
    {
        ERRLOG("结点创建失败");
        return EOF;
    }
    
    // 写入数据
    new_node->data = data;
    new_node->next = NULL;

    // 头插
    if (NULL == list->next || pos == 1)
    {
        // 没有数据的头插
        if (NULL == list->next)
        {
            list->next = new_node;
            return 0;
        }
        // 有数据的头插
        new_node->next = list->next;
        list->next = new_node;
        return 0;
    }
    // 任意位置

    Node * ptr_node = list->next;

    for (size_t i = 1; i < pos - 1 && NULL != ptr_node->next; i++)
    {
        ptr_node = ptr_node->next;
    }

    // 判断退出方式 如果下面表达式成立 则 进行尾插
    if (NULL == ptr_node->next)
    {
        ptr_node->next = new_node;
        return 0;
    }
    
    // 中间位置插入
    new_node->next = ptr_node->next;

    ptr_node->next = new_node;


    return 0;
    
}

// 单链表的删除
int delete_link_list(link_list* list, int pos)
{
    if (NULL == list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }

    if (0 == pos)
    {
        printf("pos 不能为 0\n");
        return EOF;
    }

    if (NULL == list->next)
    {
        ERRLOG("当前链表无数据");
        return EOF;
    }



    // 头删   
    // 1 == pos  用于判定 pos 头删  
    // NULL == list->next->next 用于判定只有 一个结点 只能进行头删
    if ( 1 == pos || NULL == list->next->next )
    {
        Node * ptr_1 =  list->next;
        // 头结点指向  第一个结点的下一个结点
        list->next = ptr_1->next;

        free(ptr_1);

        return 0;
    }

    Node * ptr_1 =  list->next; 
    Node * ptr_2 =  ptr_1->next;

    for (size_t i = 1; i < pos - 1 && NULL != ptr_2->next; i++)
    {
        ptr_1 = ptr_1->next;
        ptr_2 = ptr_1->next;
    }

    // 删除

    ptr_1->next = ptr_2->next;

    free(ptr_2);
    
    return 0;
}



// 单链表的遍历
int print_link_list(link_list* list)
{
    if (NULL == list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }
    if (NULL == list->next)
    {
        ERRLOG("链表内无数据");
        return EOF;
    }

    Node * ptr_node  = list->next;


    printf("姓名\t性别\t年纪\t学号\t成绩\n");
    for (size_t i = 0; NULL != ptr_node ; i++)
    {
        printf("%s\t%s\t%d\t%d\t%d\n",\
        ptr_node->data.name , ptr_node->data.sex , ptr_node->data.age ,\
        ptr_node->data.id , ptr_node->data.sco);
        ptr_node = ptr_node->next;
    }
    
    return 0;
}

// 单链表的查找
Node* find_name_link_list(link_list* list, char * name)
{
    if (NULL == list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return NULL;
    }
    if (NULL == list->next)
    {
        ERRLOG("链表内无数据");
        return NULL;
    }

    // 查找名字
    if (0 == strlen(name))
    {
        printf("请输入要查找的名字:");
        scanf("%s" , name);
    }
    
    Node * ptr_node = list->next;

    // 遍历查找
    for (size_t i = 0; NULL != ptr_node; i++)
    {
        if (!strcmp( ptr_node->data.name , name ))
        {
            return ptr_node;
        }
        ptr_node = ptr_node->next;
    }

    return NULL;
}

// 单链表的修改
int up_data_link_list(link_list* list, Node * node)
{
    if (NULL == list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }
    if (NULL == node)
    {
        ERRLOG("没找到数据");
        return EOF;
    }

    // 打印原始数据

    printf("姓名\t性别\t年纪\t学号\t成绩\n");

    printf("%s\t%s\t%d\t%d\t%d\n",\
        node->data.name , node->data.sex , node->data.age ,\
        node->data.id , node->data.sco);


    // 修改

    int num; // 记录用户的输入

 // 开始修改
    while (num != 6)
    {
        printf("1、姓名 2、性别 3、年纪 4、学号 5、成绩 6、退出");
        printf("请输入你要修改的选项:\n");
        scanf("%d", &num);

        switch (num)
        {
        case 1:
            printf("请输入姓名:");
            scanf("%s", node->data.name);
            break;
        case 2:
            printf("请输入性别:");
            scanf("%s", node->data.sex);
            break;
        case 3:
            printf("请输入年纪:");
            scanf("%d", &node->data.age);
            break;
        case 4:
            printf("请输入学号:");
            scanf("%d", &node->data.id);
            break;
        case 5:
            printf("请输入学号:");
            scanf("%d", &node->data.sco);
            break;
        case 6:
            printf("退出");
            break;
        default:
            break;
        }
    }
    
    return 0;
}

// 单链表的判空 空 -1  不空 返回 0
int IsEmpty_link_list(link_list* list)
{
    if (NULL == list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }

    if (NULL == list->next)
    {
        return EOF;
    }

    
    return 0;
}

// 单链表的清空
int clear_link_list(link_list* list)
{
    if (NULL == list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }

    Node * ptr_node_1  = list->next;
    Node * ptr_node_2  = ptr_node_1->next;

    // 销毁结点
    for (size_t i = 0; NULL != ptr_node_1 ; i++)
    {
        free(ptr_node_1);
        // 移动指针
        ptr_node_1 = ptr_node_2;

        if (NULL != ptr_node_2)
        {
            ptr_node_2 = ptr_node_2->next;
        }
    }

    return 0;
}

// 单链表的合并
int merge_link_list(link_list* list1, link_list* list2)
{
    if (NULL == list1 || NULL == list2)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }
    // list2。next 不能为空
    if (NULL == list2->next)
    {
        ERRLOG("list2 无数据");
        return EOF;
    }


    Node * ptr_2 = list2->next;

    for (size_t i = 1; NULL != ptr_2 ; i++)
    {
        insert_link_list( list1 , ptr_2->data , i );
        ptr_2 = ptr_2->next;
    }

    return 0;
}



// 单链表的销毁
int free_link_list(link_list ** list)
{
    if (NULL == *list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }

    Node * ptr_node_1  = (*list)->next;
    Node * ptr_node_2  = ptr_node_1->next;

    // 销毁结点
    for (size_t i = 0; NULL != ptr_node_1 ; i++)
    {
        free(ptr_node_1);
        // 移动指针
        ptr_node_1 = ptr_node_2;

        if (NULL != ptr_node_2)
        {
            ptr_node_2 = ptr_node_2->next;
        }
    }

    // 销毁头结点 A 获得 一级指针地址  B 获得 一级指针数据
    free(*list);

    *list = NULL; 

    return 0;
}